package com.google.code.mochaccino.framework.crypto.scheme.impl;

/*
 * Copyright 2012 Claude Houle claude.houle@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import com.google.code.mochaccino.framework.crypto.EncryptionException;
import com.google.code.mochaccino.framework.crypto.cipher.CipherHandler;
import com.google.code.mochaccino.framework.crypto.scheme.EncryptionSchemeBase;
import com.google.common.base.Preconditions;
import java.security.GeneralSecurityException;
import java.security.Key;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

/**
 * Password-Based Encryption Scheme
 *
 *
 */
public class EncryptionSchemePasswordBased extends EncryptionSchemeBase {

	private SecretKey key;

	public EncryptionSchemePasswordBased( String passphrase, int keyLength, String salt, int iterationCount, String algorithm, CipherHandler handler ) throws EncryptionException {
		this( passphrase, keyLength, salt, iterationCount, algorithm, null, handler );
	}

	public EncryptionSchemePasswordBased( String passphrase, int keyLength, String salt, int iterationCount, String algorithm, String provider, CipherHandler handler ) throws EncryptionException {
		super( algorithm, provider, handler );
		Preconditions.checkNotNull( passphrase, "Passphrase cannot be null" );
		Preconditions.checkNotNull( salt, "Salt cannot be null" );
		Preconditions.checkArgument( iterationCount > 0, "Iteration cannot be smaller than 0" );
		Preconditions.checkArgument( keyLength > 0, "Key length cannot be smaller than 0" );

		try {
			PBEKeySpec keySpec = new PBEKeySpec( passphrase.toCharArray(), salt.getBytes(), iterationCount, keyLength );
			SecretKeyFactory keyFactory = getProvider() != null ? SecretKeyFactory.getInstance( getAlgorithm(), getProvider() ) : SecretKeyFactory.getInstance( getAlgorithm() );
			key = keyFactory.generateSecret( keySpec );
		} catch ( GeneralSecurityException e ) {
			throw new EncryptionException( e );
		}
	}

	@Override
	protected Key getPrivateKey() {
		return key;
	}

	@Override
	protected Key getPublicKey() {
		return key;
	}
}
